<template>
  <div class="app-container">
    <div v-if="!relationConfig" style="position: relative; width: 100%; height: 100%">
      <echartsDom v-if="chartOptions" :chartOptions="chartOptions" />
      <px-button class="relateConfigBtn" type="primary" @click="toRelateConfig">关系配置</px-button>
    </div>

    <div v-else class="equip-wrap-common">
      <div class="equip-table-btn">
        <px-button type="primary" :icon="ArrowLeft" @click="cancel">返回</px-button>
        <px-button type="primary" @click="addBtn">新增</px-button>
      </div>
      <px-table :data="tableData" class="equip-table" height="calc(100vh - 210px)" border>
        <template #empty>
          <px-empty />
        </template>
        <px-table-column prop="indicatorName" label="中心指标" min-width="120" />
        <template v-for="(item, index) in relatedList" :key="index">
          <px-table-column prop="relatedCollectionList" :label="item.labelName" min-width="120">
            <template #default="scope">
              <div>{{ getInicatorName(scope.row.relatedCollectionList, item.className) }}</div>
            </template>
          </px-table-column>
          <px-table-column prop="machineType" label="类型" min-width="120">
            <template #default="scope">
              <div>{{ getInicatorType(scope.row.relatedCollectionList, item.className) }}</div>
            </template>
          </px-table-column>
        </template>
        <px-table-column label="操作" min-width="150" fixed="right" align="center">
          <template #default="scope">
            <px-tooltip content="编辑" placement="top">
              <px-button link icon="EditPen" type="primary" @click="handleEdit(scope.row)" />
            </px-tooltip>
            <px-tooltip content="删除" placement="top">
              <px-button link icon="Delete" type="danger" @click="handleDelete(scope.row)" />
            </px-tooltip>
          </template>
        </px-table-column>
      </px-table>
      <!-- <pagination
      v-show="total > 0"
      v-model:page="queryParams.pageNum"
      v-model:limit="queryParams.pageSize"
      class="equip-table-pagination"
      :total="total"
      @pagination="queryTable"
    /> -->
      <px-dialog v-model="dialogVisible" draggable clickHideContent :title="dialogType == 'add' ? '新增' : '编辑'" width="900" @close="closeDialog">
        <px-form ref="formRef" :model="editFormParams" label-width="120px" label-position="right" :rules="editRules">
          <px-row>
            <px-col :span="14">
              <px-form-item label="中心指标" required>
                <px-radio-group v-model="editFormParams.isNew" @change="indicatorTypeChange">
                  <px-radio label="1" size="large">自定义</px-radio>
                  <px-radio label="0" size="large">指标库</px-radio>
                </px-radio-group>
              </px-form-item>
              <px-form-item v-if="editFormParams.isNew == 1" prop="indicatorName">
                <px-input v-model="editFormParams.indicatorName" style="width: 350px" type="text" placeholder="请输入自定义指标" />
              </px-form-item>
              <px-form-item v-if="editFormParams.isNew == 0" prop="indicatorCode">
                <!-- <px-select v-model="editFormParams.indicatorCode" placeholder="请选择" style="width:100%">
                <px-option :value="editFormParams.indicatorCode" :label="editFormParams.indicatorName">
                  <px-tree-v2
                    :render-after-expand="false"
                    check-strictly
                    :data="centerIndicatorList"
                    @node-click="centerIndicatorClick"
                    :height="250"
                    ref="treeRef"
                  ></px-tree-v2>
                </px-option>
              </px-select> -->
                <px-tree-select
                  v-model="editFormParams.indicatorCode"
                  style="width: 350px"
                  :data="centerIndicatorList"
                  :render-after-expand="false"
                  check-strictly
                  @node-click="centerIndicatorClick"
                />
              </px-form-item>
            </px-col>
          </px-row>
          <px-row v-for="(item, index) in editFormParams.relatedCollectionList" :key="item.labelName" class="item-block">
            <px-col :span="14">
              <px-form-item :label="item.labelName" :prop="'relatedCollectionList.' + index + '.isNew'">
                <px-radio-group v-model="item.isNew" @change="rIndicatorTypeChange(item)">
                  <px-radio label="1" size="large">自定义</px-radio>
                  <px-radio label="0" size="large">指标库</px-radio>
                </px-radio-group>
              </px-form-item>
              <px-form-item v-if="item.isNew == 1" :prop="'relatedCollectionList.' + index + '.indicatorName'">
                <px-input v-model="item.indicatorName" style="width: 350px" type="text" placeholder="请输入自定义指标" />
              </px-form-item>
              <px-form-item v-if="item.isNew == 0" :prop="'relatedCollectionList.' + index + '.indicatorCode'">
                <!-- <px-tree-v2 
                v-model="item.indicatorCode"
                style="width: 350px"
                :data="item.indicatorList"
                multiple
                :render-after-expand="false"
                show-checkbox
                check-strictly
                check-on-click-node
                @check="(data, checkedData) => relatedCollectionCheck(item, data, checkedData)"
              /> -->
                <px-tree-select
                  v-model="item.indicatorCode"
                  style="width: 350px"
                  :data="item.indicatorList"
                  multiple
                  :render-after-expand="false"
                  show-checkbox
                  check-strictly
                  check-on-click-node
                  @check="(data, checkedData) => relatedCollectionCheck(item, data, checkedData)"
                />
              </px-form-item>
            </px-col>
            <px-col :span="8">
              <px-form-item label="类型" :prop="'relatedCollectionList.' + index + '.type'">
                <px-select v-model="item.type" clearable>
                  <px-option v-for="item in indicatorTypeList" :key="item.value" :label="item.name" :value="item.value" />
                </px-select>
              </px-form-item>
            </px-col>
          </px-row>
        </px-form>
        <template #footer>
          <span class="dialog-footer">
            <px-button @click="closeDialog">取消</px-button>
            <px-button type="primary" @click="confirmAction()"> 确定 </px-button>
          </span>
        </template>
      </px-dialog>
    </div>
  </div>
</template>
<script setup lang="ts">
import { onMounted, ref, toRefs, reactive, computed } from "vue";
import { ArrowLeft } from "@px-ui/icons-vue";
import {
  queryIndicatorConfigList,
  addIndicatorConfig,
  updateIndicatorConfig,
  deleteIndicatorConfig,
  queryMeasureList,
  queryIndicatorMatrix
} from "@/api/spc";
import { PxMessage, PxMessageBox } from "px-ui";
import echartsDom from "../components/echartsDom.vue";

const relationConfig = ref(false);
const relatedList = [
  {
    className: "MACHINE",
    labelName: "机械科关联指标"
  },
  {
    className: "ELECTRICTITY",
    labelName: "电科关联指标"
  },
  {
    className: "WATER",
    labelName: "水科关联指标"
  },
  {
    className: "GAS",
    labelName: "气化科关联指标"
  },
  {
    className: "FAB",
    labelName: "机台侧关联指标"
  }
];

const state = reactive<Record<string, any>>({
  queryParams: {
    pageNum: 1,
    pageSize: 20
  },
  indicatorLoaded: false, // 判断指标是否已经查询
  tableData: [], // 列表数据
  total: 0, // 列表数量
  centerIndicatorList: [], // 中心指标
  machineIndicatorList: [], //机械科指标
  electricityIndicatorList: [], //电科指标
  gasIndicatorList: [], //气化科指标
  waterIndicatorList: [], //水科指标
  fabIndicatorList: [], //机台侧指标
  rowData: {}, // 当前行数据
  dialogVisible: false, // 弹窗显示隐藏
  dialogType: "add", // 弹窗默认新增
  editFormParams: {},
  indicatorTypeList: [
    {
      value: "0",
      name: "关注指标"
    },
    {
      value: "1",
      name: "影响指标"
    }
  ],
  formRef: null
});
const chartOptions = ref(null);

const {
  queryParams,
  indicatorLoaded,
  tableData,
  total,
  centerIndicatorList,
  machineIndicatorList,
  electricityIndicatorList,
  gasIndicatorList,
  waterIndicatorList,
  fabIndicatorList,
  editFormParams,
  rowData,
  dialogVisible,
  dialogType,
  indicatorTypeList,
  formRef
} = toRefs(state);

onMounted(() => {
  queryMatrix();
  queryIndicatorList();
});

// 获取指标矩阵图表
const queryMatrix = () => {
  queryIndicatorMatrix({ classType: 1 }).then(res => {
    let nodes = [];
    res.nodeDtos.forEach(v => {
      let symbolSize = 20;
      if (v.category == 0) {
        symbolSize = 30;
      }
      nodes.push({
        ...v,
        name: v.indicatorName,
        symbolSize
      });
    });
    res.nodeDtos.forEach(function (node) {
      node.label = {
        show: node.value > 30
      };
    });

    chartOptions.value = {
      title: {
        text: "指标影响矩阵关系图"
      },
      tooltip: {},
      legend: [
        {
          // selectedMode: 'single',
          data: res.graphDtos.map(function (a) {
            return a.name;
          })
        }
      ],
      series: [
        {
          type: "graph",
          layout: "force", // 使用力导向布局
          data: nodes,
          links: res.linkDtos,
          categories: res.graphDtos,
          legendHoverLink: false,
          force: {
            // 力导向布局的配置项，可以调整以改变布局效果
            repulsion: 1000, // 节点之间的斥力
            edgeLength: [50, 100] // 边的长度范围
          },
          roam: true,
          label: {
            position: "right",
            formatter: "{b}"
          },
          lineStyle: {
            color: "source",
            curveness: 0.3
          },
          emphasis: {
            focus: "adjacency",
            lineStyle: {
              width: 10
            }
          }
        }
      ]
    };
  });
};

// 关系配置
const toRelateConfig = () => {
  relationConfig.value = true;
};

// 返回
const cancel = () => {
  relationConfig.value = false;
};

const checkIndicatorName = (rule, value, callback) => {
  if (editFormParams.value.isNew == 1 && !value) {
    return callback(new Error("请输入"));
  } else {
    callback();
  }
};
const checkIndicatorCode = (rule, value, callback) => {
  if (editFormParams.value.isNew == 0 && !value) {
    return callback(new Error("请选择"));
  } else {
    callback();
  }
};
const checkRelatedCollection = (rule, value, callback) => {
  if (value.every(item => !item.indicatorCode || !item.indicatorName)) {
    callback(new Error("请维护至少一项关联指标"));
  } else {
    callback();
  }
};
const valueIsEmpty = value => {
  if (value === "" || value == null || typeof value == "undefined") {
    return true;
  }
  return false;
};
const checkIndicatorType = (rule, value, callback) => {
  const index = parseInt(rule.field.split(".")[1]); //当前索引
  if (
    (editFormParams.value.relatedCollectionList[index].indicatorCode && editFormParams.value.relatedCollectionList[index].indicatorCode.length) ||
    editFormParams.value.relatedCollectionList[index].indicatorName
  ) {
    if (valueIsEmpty(value)) {
      callback(new Error("请选择"));
    } else {
      callback();
    }
  } else {
    callback();
  }
};
const editRules = computed(() => ({
  indicatorName: [{ validator: checkIndicatorName, message: "请输入", trigger: "blur" }],
  indicatorCode: [{ validator: checkIndicatorCode, message: "请选择", trigger: "change" }],
  relatedCollectionList: [
    {
      type: [{ validator: checkIndicatorType, message: "请选择", trigger: "change" }]
    }
  ]
  // relatedCollection: [{ validator: checkRelatedCollection, message: '请维护至少一项关联指标', trigger: 'blur' }],
}));
// 指标数据转成tree-select数据的格式
const convertData = node => {
  node.value = node.measureCode;
  node.label = node.measureName;
  if (node.children) {
    node.children.forEach(child => {
      convertData(child);
    });
  }
};
// 指标下拉
const queryIndicatorList = async () => {
  queryMeasureList({ className: "" }).then(res => {
    console.log(res);
    centerIndicatorList.value = res || [];
    centerIndicatorList.value.forEach(item => {
      convertData(item);
    });
  });
  queryMeasureList({ className: "ELECTRICTITY" }).then(res => {
    console.log(res);
    electricityIndicatorList.value = res || [];
    electricityIndicatorList.value.forEach(item => {
      convertData(item);
    });
  });
  queryMeasureList({ className: "MACHINE" }).then(res => {
    console.log(res);
    machineIndicatorList.value = res || [];
    machineIndicatorList.value.forEach(item => {
      convertData(item);
    });
  });
  queryMeasureList({ className: "GAS" }).then(res => {
    console.log(res);
    gasIndicatorList.value = res || [];
    gasIndicatorList.value.forEach(item => {
      convertData(item);
    });
  });
  queryMeasureList({ className: "WATER" }).then(res => {
    console.log(res);
    waterIndicatorList.value = res || [];
    waterIndicatorList.value.forEach(item => {
      convertData(item);
    });
  });
  queryMeasureList({ className: "FAB" }).then(res => {
    console.log(res);
    fabIndicatorList.value = res || [];
    fabIndicatorList.value.forEach(item => {
      convertData(item);
    });
  });
  queryTable();
};

// 查询列表
const queryTable = async () => {
  const res = await queryIndicatorConfigList({ classType: "1" });
  tableData.value = res || [];
};

const getInicatorName = (list, className) => {
  let n = [];
  let t = list.filter(v => v.classCode == className);
  if (t && t.length) {
    if (t[0].relatedIndicatorList && t[0].relatedIndicatorList.length) {
      t[0].relatedIndicatorList.forEach(item => {
        n.push(item.indicatorName);
      });
    }
  }
  return n.join(",");
};
const getInicatorType = (list, className) => {
  let t = list.filter(v => v.classCode == className);
  let type = t[0]?.type;

  return type == "1" ? "影响指标" : type == "0" ? "关注指标" : "";
};
// 关闭弹窗
const closeDialog = () => {
  formRef.value?.clearValidate();
  dialogVisible.value = false;
};
const indicatorTypeChange = () => {
  editFormParams.value.indicatorName = "";
  editFormParams.value.indicatorPath = "";
  editFormParams.value.indicatorCode = "";
};
const rIndicatorTypeChange = item => {
  editFormParams.value.relatedCollectionList.forEach(v => {
    if (v.className == item.className) {
      v.indicatorName = "";
      v.indicatorCode = [];
    }
  });
  // editFormParams.value.indicatorName = "";
  // editFormParams.value.indicatorPath = "";
  // editFormParams.value.indicatorCode = "";
};
function getParents(tree, measureCode, parents = []) {
  for (let i = 0; i < tree.length; i++) {
    if (tree[i].measureCode === measureCode) {
      // 找到目标节点，返回路径
      return [...parents, tree[i]];
    }
    if (tree[i].children) {
      let node = getParents(tree[i].children, measureCode, [...parents, tree[i]]);
      if (node) {
        return node;
      }
    }
  }
  return []; // 如果没有找到父节点，返回空数组
}
//中心指标树点击
const centerIndicatorClick = data => {
  // 取当前节点的名称，并给indicationPath赋值
  editFormParams.value.indicatorName = data.label;
  editFormParams.value.indicatorPath = data.value;
  if (data.type == "measure") {
    editFormParams.value.isIndicator = "1";
    // parents为该指标的路径数组
    let parents = getParents(centerIndicatorList.value, data.value);
    let p = parents.filter(v => v.type == "systemModel");
    if (p && p.length) {
      editFormParams.value.systemCode = p[0].measureCode;
    } else {
      editFormParams.value.systemCode = "";
    }
  } else {
    editFormParams.value.isIndicator = "0";
    editFormParams.value.systemCode = "";
  }
};
// const relatedCollectionChange = (item,data,checked,indeterminate) => {
//   debugger
// }
const relatedCollectionCheck = (item, data, checkedData) => {
  let checkedCodes = [],
    checkedNames = [];
  let tmpList = [];
  checkedData.checkedNodes.forEach(v => {
    let systemCode = "",
      indicatorPath = v.value,
      indicatorName = v.label,
      isIndicator = "";
    if (v.type == "measure") {
      isIndicator = "1";
      // parents为该指标的路径数组
      let parents = getParents(item.indicatorList, v.value);
      let p = parents.filter(n => n.type == "systemModel");
      if (p && p.length) {
        systemCode = p[0].measureCode;
      } else {
        systemCode = "";
      }
    } else {
      isIndicator = "0";
      systemCode = "";
    }
    tmpList.push({
      systemCode,
      indicatorPath,
      indicatorName,
      isIndicator
    });
    checkedCodes.push(v.value);
    checkedNames.push(v.label);
  });
  editFormParams.value.relatedCollectionList.forEach(v => {
    if (v.className == item.className) {
      v.indicatorName = checkedNames.toString();
      v.indicatorCode = checkedCodes;
      v.relatedIndicatorList = tmpList;
    }
  });
};
const getInicatorList = className => {
  if (className == "MACHINE") {
    return machineIndicatorList.value;
  }
  if (className == "ELECTRICTITY") {
    return electricityIndicatorList.value;
  }
  if (className == "WATER") {
    return waterIndicatorList.value;
  }
  if (className == "GAS") {
    return gasIndicatorList.value;
  }
  if (className == "FAB") {
    return fabIndicatorList.value;
  }
};
const getInicatorInfo = (className, list) => {
  let t = list.filter(v => v.classCode == className);
  let codes = [],
    names = [],
    type = "",
    isNew = "0",
    id = "",
    relatedIndicatorList = [];
  if (t && t.length) {
    codes = t[0].relatedIndicatorList.map(item => item.indicatorPath);
    names = t[0].relatedIndicatorList.map(item => item.indicatorName);
    type = !valueIsEmpty(t[0].type) ? t[0].type : "";
    isNew = !valueIsEmpty(t[0].isNew) ? t[0].isNew : "0";
    id = t[0].id;
    relatedIndicatorList = t[0].relatedIndicatorList;
  }
  return {
    codes,
    names: names.toString(),
    id,
    type,
    isNew,
    relatedIndicatorList
  };
};
const getRelatedCollection = row => {
  let tmpList = [];
  relatedList.forEach(v => {
    let cn = getInicatorInfo(v.className, row.relatedCollectionList || []);
    tmpList.push({
      ...v,
      id: cn.id || "",
      isNew: cn.isNew,
      indicatorList: getInicatorList(v.className),
      relatedIndicatorList: cn.relatedIndicatorList || [],
      indicatorCode: cn.codes,
      indicatorName: cn.names,
      type: cn.type
    });
  });
  return tmpList;
};
// 新增-显示弹窗
const addBtn = () => {
  dialogType.value = "add";
  editFormParams.value = {
    id: "",
    indicatorPath: "",
    indicatorName: "",
    indicatorCode: "",
    isNew: "0",
    relatedCollectionList: getRelatedCollection({})
  };
  dialogVisible.value = true;
};
// 编辑-显示弹窗
const handleEdit = (row: any) => {
  dialogType.value = "edit";
  rowData.value = row;
  editFormParams.value = {
    id: row.id,
    systemCode: row.systemCode,
    isIndicator: row.isIndicator,
    indicatorPath: row.indicatorPath, //拼接 or 还是先只存选中的？
    indicatorName: row.indicatorName, //拼接 or 还是先只存选中的?
    indicatorCode: row.indicatorPath, //叶子
    isNew: valueIsEmpty(row.isNew) ? "0" : row.isNew,
    relatedCollectionList: getRelatedCollection(row)
  };
  dialogVisible.value = true;
};
// 删除
const handleDelete = async (row: any) => {
  PxMessageBox.confirm("要删除当前配置吗？", "提示", {
    confirmButtonText: "删除",
    confirmButtonClass: "px-button--danger",
    cancelButtonText: "取消",
    type: "warning",
    draggable: true
  })
    .then(async () => {
      await deleteIndicatorConfig({ id: row.id });
      PxMessage.success("删除成功");
      queryTable();
    })
    .catch(() => {});
};

const confirmAction = () => {
  // 保存指标信息 组装保存参数
  // editFormParams.value 去除多余字段
  formRef.value?.validate(async (valid, fields) => {
    if (valid) {
      // 至少维护一个关联指标
      let data = editFormParams.value.relatedCollectionList.filter(v => (v.indicatorCode && v.indicatorCode.length) || v.indicatorName);
      if (!data || !data.length) {
        PxMessage.error("至少维护一个关联指标");
        return;
      }

      let funName = addIndicatorConfig;
      if (dialogType.value == "edit") {
        funName = updateIndicatorConfig;
      }
      // 组装需要的数据
      let params = {
        id: editFormParams.value.id,
        isNew: editFormParams.value.isNew,
        indicatorPath: editFormParams.value.isNew != 1 ? editFormParams.value.indicatorCode : "",
        indicatorName: editFormParams.value.indicatorName,
        relatedCollectionList: [],
        classType: "1", // 0 四科 1 水科
        isIndicator: editFormParams.value.isIndicator,
        systemCode: editFormParams.value.systemCode
      };
      editFormParams.value.relatedCollectionList.forEach(v => {
        let tl = [];
        if (v.isNew != 1) {
          params.relatedCollectionList.push({
            id: v.id,
            isNew: v.isNew,
            type: v.type,
            classCode: v.className,
            relatedIndicatorList: v.relatedIndicatorList
          });
        } else {
          params.relatedCollectionList.push({
            id: v.id,
            isNew: v.isNew,
            type: v.type,
            classCode: v.className,
            relatedIndicatorList: [
              {
                indicatorPath: "",
                indicatorName: v.indicatorName
              }
            ]
          });
        }
      });
      let res = await funName({ ...params });
      PxMessage.success(dialogType.value == "edit" ? "更新成功" : "保存成功");
      closeDialog();
      queryTable();
    } else {
      console.log("error submit!", fields);
    }
  });
};
</script>

<style scoped lang="scss">
@import url("@/views/all/equip/scss/table-list.scss");

.equip-wrap-common {
  height: calc(100vh - 180px);
  padding: 0;

  .equip-form {
    margin-bottom: 8px;

    :deep(.px-form-item) {
      width: 20%;
      margin-bottom: 8px;
    }

    :deep(.px-button) {
      margin-top: -8px;
    }
  }
}

.item-block {
  padding-top: 10px;
  margin-bottom: 12px;
  border: 1px dashed #dcdcdc;
}

.equip-table-btn {
  display: flex;
  justify-content: space-between;
}

.relateConfigBtn {
  position: absolute;
  right: 0;
  bottom: 0;
}
</style>
